// <copyright file="Projectile.cs" company="SpaceRock Team Members">
// Project: SpaceRock
// File: Projectile.cs (5,52 KB, 177 lines)
// Creation date: 2010-05-28 13:53
// Last modified: 2010-06-13 03:34
// </copyright>

#region File Description
//-----------------------------------------------------------------------------
// Projectile.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using directives
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Oops.Xna.Framework.Physics;
using SpaceRockTeam.SpaceRock.Data;
using System;
#endregion

namespace Particle3DSample
{
    /// <summary>
    /// Projectile
    /// </summary>
    class Projectile : IProjectile
    {
        /// <summary>
        /// Collision shape
        /// </summary>
        public CollisionBox collisionShape;

        /// <summary>
        /// 
        /// </summary>
        private const float trailParticlesPerSecond = 200;

        /// <summary>
        /// 
        /// </summary>
        private const int numExplosionParticles = 30;

        /// <summary>
        /// 
        /// </summary>
        private const int numExplosionSmokeParticles = 50;

        /// <summary>
        /// 
        /// </summary>
        private const float projectileLifespan = 2.0f;

        /// <summary>
        /// Explosion particles
        /// </summary>
        private ParticleSystem explosionParticles;

        /// <summary>
        /// Explosion smoke particles
        /// </summary>
        private ParticleSystem explosionSmokeParticles;

        /// <summary>
        /// Trail emitter
        /// </summary>
        private ParticleEmitter trailEmitter;

        /// <summary>
        /// Position
        /// </summary>
        private Vector3 position;

        /// <summary>
        /// Velocity
        /// </summary>
        private Vector3 velocity;

        /// <summary>
        /// Age
        /// </summary>
        private float age;

        /// <summary>
        /// Should explode
        /// </summary>
        public bool ShouldExplode { get; set; } // ShouldExplode

        /// <summary>
        /// Random
        /// </summary>
        private static Random random = new Random();

        /// <summary>
        /// Explosion listener
        /// </summary>
        public IExplosionListener ExplosionListener { get; set; } // Explo

        /// <summary>
        /// Physics
        /// </summary>
        public PhysicsComponent Physics { get; set; } // Physics

        /// <summary>
        /// Constructs a new projectile.
        /// </summary>
        public Projectile(ParticleSystem explosionParticles,
                          ParticleSystem explosionSmokeParticles,
                          ParticleSystem projectileTrailParticles, Vector3 projectilePosition, Vector3 vel,
            IExplosionListener explosionListener, PhysicsComponent physics)
        {
            ExplosionListener = explosionListener;
            this.explosionParticles = explosionParticles;
            this.explosionSmokeParticles = explosionSmokeParticles;

            position = projectilePosition;
            velocity = vel;

            trailEmitter = new ParticleEmitter(projectileTrailParticles,
                                               trailParticlesPerSecond, position);

            collisionShape = new CollisionBox();
            collisionShape.Tag = this;
            collisionShape.Extents = new Vector3(2, 2, 2);
            RigidBody missleBody = new RigidBody();
            random = new Random();
            missleBody.VelocityLimit = 100;
            missleBody.Acceleration = Vector3.Zero;
            missleBody.CollisionGroup.CollisionShapes.Add(collisionShape);
            missleBody.CalculateMassProperties(10.0f);

            Vector3 position2 = position;
            missleBody.UpdateTransform(ref position2);

            Physics = physics;
            physics.RigidBodies.Add(missleBody);
        } // Projectile

        /// <summary>
        /// Updates the projectile.
        /// </summary>
        public bool Update(GameTime gameTime)
        {
            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

            position += velocity * elapsedTime;
            collisionShape.CollisionGroup.RigidBody.Position = position;
            age += elapsedTime;

            // Update the particle emitter, which will create our particle trail.
            trailEmitter.Update(gameTime, position);

            // If enough time has passed, explode! Note how we pass our velocity
            // in to the AddParticle method: this lets the explosion be influenced
            // by the speed and direction of the projectile which created it.
            if (age > projectileLifespan || ShouldExplode)
            {
                // First the light
                for (int i = 0; i < numExplosionParticles; i++)
                    explosionParticles.AddParticle(position, velocity);

                for (int i = 0; i < numExplosionSmokeParticles; i++)
                    explosionSmokeParticles.AddParticle(position, velocity);

                // Than the sound :)
                if (ExplosionListener != null)
                {
                    ExplosionListener.OnExplosion(this);
                    Physics.RigidBodies.Remove(collisionShape.CollisionGroup.RigidBody);
                }
                return false;
            } // if
                
            return true;
        } // Update
    } // class Projectile
} // namespace Particle3DSample
